﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data.Common;
using System.Data;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace CRUDPh
{
    public class DS_NET: IDS
    {
        static ManualResetEvent _clientDone = new ManualResetEvent(false);
        const int TIMEOUT_MILLISECONDS = 5000;
        const int MAX_BUFFER_SIZE = 2048;
        public override IDS IsReady(string Fname)
        {

            path = Fname;
            IDS ret = null;
            string[] strArray = path.Split('*');
            string extension = strArray[0];
            if (extension == "NET")
            {
                ret = this;               
            }
            else
            {
                if (!(next == null)) ret = next.IsReady(Fname);
            }
            return ret;
        } 
        public override void Create(Person pp)
        {
            string strArray="";           
            strArray += pp.SaveToSCV();
            strArray += " ";           
            string message = "Cr*" + path +"*"+ strArray;
            connect(message);
        }

       
        public override void Update(Person pp)
        {
            string message = "Up*" + path + "*" + pp.SaveToSCV();
            connect(message);
        }

        public override void Delete(int id)
        {
            string message = "Del*" + path +"*"+id.ToString();
            connect(message);
        }
        public MyList Read()
        {
            MyList x = new MyList();

            string message = "R*" + path;
            connect(message);
            message = getAnswer();

            string[] strArray = message.Split(';', '*');
            {
                message = getAnswer();
            }

            for (int j = 0; j < strArray.Length; j++)
            {
                if (strArray[j] == "list")
                {
                    for (int k = j + 1; k < strArray.Length - j; k++)
                    {
                        if (strArray[k] == "MySerialization.Person")
                        {
                            string[] tmp = new string[5];
                            Array.Copy(strArray, k, tmp, 0, 5);
                            Person p = new Person();
                            p.LoadFromCSV(tmp);
                            x.Add(p);
                        }
                    }
                }
            }
            return x;
        }
        Socket sender = null;
        void connect(string messageToSend)
        {
            sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            string result;
            byte[] msg = Encoding.UTF8.GetBytes(messageToSend);

            DnsEndPoint hostEntry = new DnsEndPoint("Lucky", 13000);
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.RemoteEndPoint = hostEntry;

            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
            {
                result = e.SocketError.ToString();
                _clientDone.Set();
            });

            _clientDone.Reset();

            sender.ConnectAsync(socketEventArg);

            _clientDone.WaitOne(TIMEOUT_MILLISECONDS);

            ///
            ///

            socketEventArg = new SocketAsyncEventArgs();

            socketEventArg.RemoteEndPoint = sender.RemoteEndPoint;
            socketEventArg.UserToken = null;

            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
            {
                result = e.SocketError.ToString();

                _clientDone.Set();
            });

            socketEventArg.SetBuffer(msg, 0, msg.Length);

            _clientDone.Reset();

            sender.SendAsync(socketEventArg);

            _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
           
        }

        string getAnswer()
        {
            string response = "Operation Timeout";

            if (sender != null)
            {
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = new DnsEndPoint("Amigo-UA", 13001);

                socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);

                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                {
                    if (e.SocketError == SocketError.Success)
                    {
                        response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
                        response = response.Trim('\0');
                    }
                    else
                    {
                        response = e.SocketError.ToString();
                    }

                    _clientDone.Set();
                });
                _clientDone.Reset();

                sender.ReceiveAsync(socketEventArg);

                while (response == "Operation Timeout")
                {
                    _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
                }
            }
            else
            {
                response = "Socket is not initialized";
            }

            return response;
        }
    }
}
